package com.yqr.server2;

import com.sohu.idcenter.IdWorker;
import com.yqr.server2.persistence.model.Account;
import com.yqr.server2.persistence.model.Order;
import com.yqr.server2.persistence.model.Repo;
import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.api.GlobalTransactionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: springclouddubbotest
 * @description: sf
 * @author: Mr.Qian
 * @create: 2021-03-16 17:19
 **/
@Service
@Slf4j
public class TestService {
    
    private Lock lock = new ReentrantLock();
    @Autowired
    private RepoService repoService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private AccountService accountService;
    
    @Autowired
    private IdWorker idWorker;
    
    /**
     *
     * @return
     * @throws TransactionException
     */
    @GlobalTransactional
    public Object testRollback(Long userId) throws TransactionException {
        log.info("seata分布式事务Id:{}", RootContext.getXID());
        lock.lock();
        try {
            LocalDateTime now = LocalDateTime.now();
            Repo repo= repoService.selectById(1L);
            
            if (repo.getCount() > 0) {
                Account account = accountService.selectById(userId);
                Order orders = new Order();
                orders.setId(idWorker.getId());
                orders.setProductCode(repo.getProductCode());
                orders.setCount(1);
                orders.setUserId(account.getId());
                repo.setCount(repo.getCount() - 1);
                account.setBalance(account.getBalance()-100);
                repoService.updateSelective(repo);
                accountService.updateSelective(account);
                orderService.add(orders);
//                int i = 1 / 0;
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            // TODO: handle exception
            log.error("载入事务id进行回滚",e);
            GlobalTransactionContext.reload(RootContext.getXID()).rollback();
            return false;
        } finally {
            lock.unlock();
        }
    }
    
//    /**
//     *
//     * @return
//     * @throws TransactionException
//     */
//    @Override
//    @GlobalTransactional
//    public Object testCommit() throws TransactionException {
//        lock.lock();
//        try {
//            LocalDateTime now = LocalDateTime.now();
//            Product product = productService.getOne(Wrappers.<Product>query().eq("id", 1).last("for update"));
//            if (product.getStock() > 0) {
//                logger.info("seata分布式事务Id:{}", RootContext.getXID());
//                Account account = accountService.getById(1);
//                Orders orders = new Orders();
//                orders.setCreateTime(now);
//                orders.setProductId(product.getId());
//                orders.setReplaceTime(now);
//                orders.setSum(1);
//                orders.setAmount(product.getPrice());
//                orders.setAccountId(account.getId());
//                product.setStock(product.getStock() - 1);
//                account.setSum(account.getSum() != null ? account.getSum() + 1 : 1);
//                account.setLastUpdateTime(now);
//                productService.updateById(product);
//                accountService.updateById(account);
//                ordersService.save(orders);
//                return true;
//            } else {
//                return false;
//            }
//        } catch (Exception e) {
//            // TODO: handle exception
//            logger.info("载入事务{}进行回滚" + e.getMessage(), RootContext.getXID());
//            GlobalTransactionContext.reload(RootContext.getXID()).rollback();
//            return false;
//        } finally {
//            lock.unlock();
//        }
//    }
}
